package com.kinroy.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kinroy.reggie.entity.Dish;
import com.kinroy.reggie.entity.DishDto;
import com.kinroy.reggie.entity.DishFlavor;
import com.kinroy.reggie.mapper.DishMapper;
import com.kinroy.reggie.service.DishFlavorService;
import com.kinroy.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    @Autowired
    private DishFlavorService dfs;

    /*添加菜品时，还会添加对应菜品的口味，这样一来，我们一次菜品添加要会对两个表进行操作，
     * 一个是dish 另一个是 dishFlavor 我们的dish的service没有对应操作两张表的方法，在这我们就来
     * 添加自己的业务实现。
     *
     * */
    @Transactional
    @Override
    public void saveWithDishFlavor(DishDto dishDto) {
        /*先把Dish存入对应的表中*/
        boolean dishSave = this.save(dishDto);
        /*从dishDto中取出我们的菜品喜好属性，菜品喜好中是需要当前添加菜品的id的，我现在就是有一个疑问啊，
         * 菜品还没添加到数据库中自动生成id，而是在我们用一个实体封装的时候就有id了，也就是前端传过来的dish数据，
         * 原本就有id了，这是怎么实现的，是在封装的时候自动生成的？
         * */

        /*从dto中获取菜品喜好，并且为这些喜好附上dish的id*/
        Long id = dishDto.getId();

        List<DishFlavor> flavors = dishDto.getFlavors();

        /*使用流的方式来给flavors集合中的每一个flavor 附上DishId属性*/
        flavors.stream().map((item) -> {
            item.setDishId(id);
            return item;
        }).collect(Collectors.toList());

        //通过调用 saveBatch（）可以一次性把一个集合的元素全部按顺序存入
        boolean saveFlavorsBatch = dfs.saveBatch(flavors);

    }


    /*数据回显的时候用的是dto，所以要查两个表，在这里我们就再自定义一下业务*/
    @Transactional
    @Override
    public DishDto show(Long id) {
        Dish dish = this.getById(id);
        Long dishId = dish.getId();
        LambdaQueryWrapper<DishFlavor> lqw = new LambdaQueryWrapper<>();
        lqw.eq(DishFlavor::getDishId, dishId);
        List<DishFlavor> dishFlavors = dfs.list(lqw);
        DishDto dishDto = new DishDto();
        dishDto.setFlavors(dishFlavors);
        //对象拷贝
        BeanUtils.copyProperties(dish, dishDto);
        return dishDto;
    }

    /*修改菜品的时候用的也是dto，同时也要修改两个表，一个dish表和一个dishFlavor表 在这里我自定义了一下业务*/
    @Transactional
    @Override
    public void updateWithDishFlavor(DishDto dishDto) {
        /*先从dishDto中分别dish 和dishFlavors*/
        List<DishFlavor> flavors = dishDto.getFlavors();
        /*对符合修改条件的dishFlavors进行批量update，同时如果新增了一些口味的话，我们还需要进行新增的处理，
         * 不然这个update只能修改原有基础的口味，新增新的口味是不会被加进去的，我们要解决这个问题,解决的方法很简单，
         * 我们可以把之前这个这个dish相关的所有口味全部删除，然后再添加咱们修改好的口味进行。
         * */

        //获取到的flavors中的dishId是null，我们要用stream流统一设置一下dishid。
        flavors.stream().map((item)->{
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());

        /*删除原来的口味记录*/
        Long dishId = dishDto.getId();
        LambdaQueryWrapper<DishFlavor> lqw=new LambdaQueryWrapper<>();
        lqw.eq(DishFlavor::getDishId,dishId);
        boolean remove = dfs.remove(lqw);
        /*把修改后的新的口味数据添加到数据库中*/
        for (int i = 0; i < flavors.size(); i++) {
            DishFlavor dishFlavor = flavors.get(i);
            dfs.save(dishFlavor);
        }

        /*dish的update*/
        this.updateById(dishDto);


    }


    /*移动端的index页面中要显示菜品信息和菜品的口味选择，所有在这里我们就定义一下业务*/
    @Transactional
    @Override
    public List<DishDto> listwithDishFlavor(Long categoryId ,Long status){
        LambdaQueryWrapper<Dish> lqw1=new LambdaQueryWrapper<>();
        lqw1.eq(Dish::getCategoryId,categoryId);

        List<Dish> list = this.list(lqw1);
        List<DishDto> List=new ArrayList<>();

        /*这个copy有问题，debug的时候发现了，不能够copy集合的，只能够copy对象的，完了完了完了
        * 被发现了。
        * */
       /* BeanUtils.copyProperties(list,List);*/

        //把list的集合内的对象全部copy到list中
        for (int i = 0; i < list.size(); i++) {
            DishDto dishDto=new DishDto();
            BeanUtils.copyProperties(list.get(i),dishDto);
            List.add(dishDto);
        }


        /*判断是不是移动端发来的请求，是移动端发来的请求会携带的status，而且status==1L
        * 如果不是就直接返回就好了。
        * */
        if (status ==null){
            return List;
        }

        /*给我们的List<dishDto> 中每一个对象都加上自己对应的口味集合list*/
        List.stream().map((item)->{
            Long dishId = item.getId();
            LambdaQueryWrapper<DishFlavor> lqw=new LambdaQueryWrapper<>();
            lqw.eq(DishFlavor::getDishId,dishId);
            List<DishFlavor> flavorsList = dfs.list(lqw);
            item.setFlavors(flavorsList);
            return item;
        }).collect(Collectors.toList());

        return List;
    }




}
